/*
JETware Hands-free Extension provides additional features for Windows Mobile HFP support.
Copyright (C) 2004-2009 Jim Thatcher

This program is free software; you can redistribute it and/or modify it under the terms of the 
GNU General Public License as published by the Free Software Foundation; version 2 of the License.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; 
if not, write to the Free Software Foundation, Inc., 
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

Source Control header

$Workfile: BTHFExt.h $
$Revision: 29 $
$Date: 6/05/07 1:49p $
*/
#include "stdafx.h"

#include <windows.h>
#include <simmgr.h>
#include <phone.h>

#define IOCTL_AG_OPEN_AUDIO         0x01
#define IOCTL_AG_CLOSE_AUDIO        0x02
#define IOCTL_AG_OPEN_CONTROL       0x0A
#define RK_AUDIO_GATEWAY            _T("SOFTWARE\\Microsoft\\Bluetooth\\AudioGateway")
#define RK_AUDIO_GATEWAY_DEVICES    (RK_AUDIO_GATEWAY TEXT("\\Devices"))
#define RK_AG_SERVICE               _T("Services\\BTAGSVC")
typedef DWORD (*PFN_SendATCommand) (LPSTR szCommand, DWORD cbCommand);

// StatusMonitor.cpp
DWORD InitializeTAPI();
void CleanupTAPI();
BOOL GetOperator(TCHAR * szOperator);
void InitializeSession(BOOL bStartSession);
void CleanupSession();
void CleanupSessionState();
DWORD GetIMEI(CHAR * szIMEI, DWORD dwSize);
DWORD GetIMSI(CHAR * szIMSI, DWORD dwSize);
void KickMonitorThread();

#define HWINFO_MFR		0x0004
#define HWINFO_MODEL	0x0002
#define HWINFO_VER		0x0001
#define HWINFO_ALL_TAPI	0x0007
#define HWINFO_OEM		0x0008

void ReadHardwareDeviceString(TCHAR * szDeviceString, WORD wFlags);

UINT NumHeldCalls();
void UpdateIndicators();
void OutputCurrentCallList();
void AddTempCall();
void PostResponse(LPSTR szResponse);
void PostNewMail(LPSTR szResponse);
void ReportCallSetup();

extern CRITICAL_SECTION csStatus;
extern CRITICAL_SECTION csCommand;
extern CRITICAL_SECTION csURQ; //Unsolicited Responses Queue
extern BOOL g_bReportECID;
extern BOOL g_bReportCID;
extern DWORD g_dwBatteryLevel; // percentage of battery remaining
extern DWORD g_dwSignalLevel;  // 0-0xFFFF
extern BOOL g_bRoaming;
extern BOOL g_bReportStatus;
extern BOOL g_bInCall;
extern BOOL g_bService;
extern DWORD g_dwCallSetup;
extern HANDLE hBAG;
extern DWORD g_dwBagPowerReq;
extern DWORD g_dwNumVoiceCalls;
extern BOOL bInSession;

#define CALLSETUP_NONE		0
#define CALLSETUP_INCOMING	1
#define CALLSETUP_OUTGOING	2
#define CALLSETUP_OUTRING	3

#define ERR_NONE              0
#define TAPI_VERSION_1_0      0x00010003
#define TAPI_VERSION_1_4      0x00010004
#define TAPI_VERSION_2_0      0x00020000

// HandsFreeExt.cpp
void InitializeResponse();
void AddLineToResponse(LPSTR szCommand, BOOL bFinal);
void SendATCommand(LPSTR szCommand);
void SendKeys(CHAR * pKeys, int nCount);
void ConnectAudio();
void DisconnectAudio();
void SuspendDevice();
void ResumeDevice();

extern BOOL g_bNeedExtraStatus;
extern HANDLE g_hInst;
extern BOOL g_bIsSmartPhone;
extern BOOL g_bDialingInitiated;
extern BOOL g_bAnsweringCall;
extern WORD g_wConvertToCharSet;
extern DWORD g_dwPSSelected;
extern DWORD g_dwMSSelected;
extern DWORD g_dwMsgFormat;
extern CHAR MSLIST[2][3];
extern CHAR * g_szInitiateVoiceDialNumber;

#define SABD 0x44424153

#define BVRA 0x41525642
#define BLDN 0x4E444C42
#define CGMI 0x494D4743
#define CGMM 0x4D4D4743
#define CGMR 0x524D4743
#define CIND 0x444E4943
#define CMER 0x52454D43
#define CMGD 0x44474D43
#define CMGF 0x46474D43
#define CMGR 0x52474D43
#define CNMI 0x494D4E43
#define CPBR 0x52425043
#define CPBS 0x53425043
#define CPMS 0x534D5043
#define CSCS 0x53435343
#define COPS 0x53504F43
#define CNUM 0x4D554E43
#define BRSF 0x46535242
#define CSQ  0x0D515343
#define CBC  0x0D434243
#define CIMI 0x494D4943
#define CGSN 0x4E534743
#define CPIN 0x4E495043
#define CCLK 0x4B4C4343
#define CKPD 0x44504B43
#define CHLD 0x444C4843
#define CCWA 0x41574343
#define CLIP 0x50494C43
#define NREC 0x4345524E
#define CHUP 0x50554843
// Audi
#define CREG 0x47455243
#define CLCC 0x43434C43
#define CPAS 0x53415043
// SonyEricsson HCB-700
#define CLAN 0x4E414C43
#define SEAM 0x4D414553
// Tekkeon EZ3000
#define EIPS 0x53504945


#define BMWJUNK 0xF5AC0238

#define ERR_OK		0
#define ERR_ERROR	1
#define ERR_CMEERR	1000
#define ERR_CMSERR	2000 // subtract 1000 to get actual CMS error number
#define ERR_NOERR	0xFFFFFFFF

//RegSettings.cpp
#define NO_LIMIT		-1

void GetRegSettings();
extern TCHAR * g_szExtChainDll;
extern TCHAR * g_szContactFilter;
extern BOOL  g_bIncludeNoCat;
extern DWORD g_dwIncludeFax;
extern DWORD g_dwMaxContacts[8];
extern DWORD g_dwInvertRoam;
extern DWORD g_dwInCallInterval;
extern DWORD g_dwIdleInterval;
extern DWORD g_dwReportIMI;
extern TCHAR * g_szMfrString;
extern TCHAR * g_szModelString;
extern TCHAR g_szPowerResumeName[16];
extern TCHAR g_szPowerSuspendName[16];
// extern TCHAR g_szHFDevName[64]; //FIX: 1.22: Use thread ID to determine start and end of session
// extern BOOL  g_bDeviceChanged;
extern DWORD g_dwSessionThreadId;
extern DWORD g_dwMainProcessId;

extern DWORD g_dwHandleCMER;
extern DWORD g_dwHandleCIND;
extern DWORD g_dwHandleCLIP;
extern DWORD g_dwHandleCHUP;
extern DWORD g_dwHandleCKPD;
extern DWORD g_dwHandleCPBS;
extern DWORD g_dwHandleCPMS;
extern DWORD g_dwFeatureMask;
extern DWORD g_dwInBandRing;
extern DWORD g_dwSleepOnDisconnect;
extern DWORD g_dwReportCIDName;
extern DWORD g_dwMaxPBName;
extern DWORD g_dwShortResponse;
extern DWORD g_dwPBCountTimeout;

#define CMD_INTERNAL_ONLY	0
#define CMD_LOCAL_ONLY		1
#define CMD_BOTH			2

#define FM_CLCC_USEID		0x00000001
#define FM_CLCC_ATD_FAKE	0x00000002
#define FM_CLCC_NOTIFY		0x00000004
#define FM_CPBS_NO_COUNT	0x00000008
#define FM_FORCE_POWER_ON	0x00000010
#define FM_RESUME_ON_DIAL	0x00000020
#define FM_RESET_AUDIO		0x00000040
#define FM_KEEP_AUDIO_ON	0x00000080
#define FM_LAST_NAME_FIRST	0x00000100
#define FM_NOPING_HF_CTRL	0x00000200
#define FM_HI_PRI_THREADS	0x00000400
#define FM_CS_PROTECT_RESP	0x00001000
#define FM_CS_NOPROTECT		0x00002000
#define FM_EARLY_REGREAD	0x00004000
#define FM_DEV_OVERRIDE		0x80000000

// Parrot 3200LS workarounds
extern DWORD g_dwPbSwapMeSm;
extern DWORD g_dwReportSimMax;

// TextMapping.cpp
BOOL ConvertString(CHAR *lpDest, TCHAR *szSource, WORD wLen);
void MapToGSM(CHAR *lpDest, TCHAR *szSource, WORD wLen, BOOL bCID);
void MapToUcs2(CHAR *lpDest, TCHAR *szSource, WORD wLen);
int ascii_to_pdu(char *ascii, unsigned char **pdu);
int pdu_to_ascii(unsigned char *pdu, int pdulength, char **ascii);

// Contacts.cpp
int StripPhoneNumber(TCHAR * pszIn, TCHAR * pszOut, int nLen);
void ResetContacts();
BOOL InitializeOutlook();
BOOL FindContact(LPTSTR lpNumber, LPTSTR lpName);
DWORD CountContacts();
void CleanupOutlook();
int ReadContacts(int nRecord, int nEnd);
int ReadSIMContacts(DWORD dwLoc, int nRecord, int nEnd);
// int CountCallContacts(int nType);
int ReadCallContacts(int nRecord, int nEnd, int nType);

extern int g_nNumContacts;

#define QUERY			'?'

#define CONTACTS_ME		0
#define CONTACTS_SM		1
#define CONTACTS_DC		2
#define CONTACTS_RC		3
#define CONTACTS_MC		4
#define CONTACTS_LD		5 // SIM Last Dialed numbers
#define CONTACTS_FD		6 // SIM Fixed Dialing numbers
#define CONTACTS_ON		7 // SIM Own numbers

#define MESSAGES_ME		0
#define MESSAGES_SM		1
// #define MESSAGES_OT		2

#define MSG_FORMAT_PDU	0
#define MSG_FORMAT_TEXT	1
#define MSG_CODING_7BIT	0
#define MSG_CODING_8BIT	4

#define CHARSET_GSM		0
#define CHARSET_UTF8	1
#define CHARSET_UCS2	2



#define CALLS_DIALED	2
#define CALLS_RECEIVED	3
#define CALLS_MISSED	4

// Messages.cpp
extern DWORD g_dwSMSTotal;
extern DWORD g_dwSMSUsed;
extern HSIM g_hSIM;
// extern CHAR g_szNumber[32];
extern TCHAR * g_szMsgStore[2];
extern DWORD g_dwMsgMax[2];
extern BOOL g_bAllMsgs[2];
extern CRITICAL_SECTION csMsgList;
extern BOOL bProcessingNewMail;

#define DUMMY_MSG_COUNT 0

BOOL InitializeSIM();
void CleanupSIM();
DWORD GetSIMMessageCount();
DWORD InitializeMAPI();
void CleanupMAPI();
// DWORD GetMapiMessageCount();
void SetMapiNotify(DWORD dwMsgStore, BOOL bNotify, WORD wMode);
BOOL GetMapiNotify();
WORD GetMapiNotifyMode();
void ReadMessage(int nIndex);
BOOL ReadMapiMessage(int nIndex);
BOOL DeleteMapiMessage(int iIndex);
void CheckForNewMessages();
BOOL GetMyNumber(CHAR * szNumber, DWORD dwLen);

// Debugging stuff
#define LOG_REQUESTS		0x0001
#define LOG_RESPONSES		0x0002
#define LOG_NOTIFICATIONS	0x0004
#define LOG_SMS_NOTIFY		0x0008

#define DEBUG_REQUESTS		0x0001
#define DEBUG_CONTACTS		0x0010
#define DEBUG_INDICATORS	0x0020
#define DEBUG_MESSAGES		0x0040
// #define DEBUG_POOM			0x0020
#define DEBUG_POWER			0x0080
#define DEBUG_CALLERID		0x0100
#define DEBUG_CHAIN			0x0200
#define DEBUG_INFO			0x0400
// #define DEBUG_STARTUP		0x0400
#define DEBUG_SIM			0x0800
#define DEBUG_CATEGORIES	0x1000
#define DEBUG_INSTALL		0x2000
#define DEBUG_VOICEDIAL		0x4000
#define DEBUG_INBANDRING	0x8000

// Put really chatty items in high word
#define DEBUG_CONTACT_DETAIL	0x10000
#define DEBUG_TAPI				0x20000
#define DEBUG_NOTIFY			0x40000
#define DEBUG_THREADING			0x80000


extern DWORD g_dwDebugLevels;

void LogString(LPSTR szCommand, DWORD dwLevel);
